package com.ybxiang.camera_opengl

import android.graphics.SurfaceTexture
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import androidx.camera.core.Preview
import androidx.lifecycle.LifecycleOwner
import com.ybxiang.camera_opengl.filter.CameraFilter
import com.ybxiang.camera_opengl.utils.CameraHelper
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

/**
 * Created by yunbo.xiang on 2021/12/15
 * Describe:
 */
class CameraRender(private val mCameraView: CameraView) : GLSurfaceView.Renderer,
    SurfaceTexture.OnFrameAvailableListener, Preview.OnPreviewOutputUpdateListener {
    /**
     * 摄像头的图像 用OpenGL ES 画出来
     */
    private lateinit var mCameraTexture: SurfaceTexture
    private var mTextTureId: Int = 0

    private val mtx = FloatArray(16)
    private lateinit var mCameraFilter: CameraFilter

    init {
        val lifecycleOwner = mCameraView.context as LifecycleOwner
        CameraHelper.init(lifecycleOwner, this)
    }


    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        // 创建纹理ID，把摄像头的数据与这个纹理关联
        // 当做能在opengl用一个图片的ID
        mCameraTexture.attachToGLContext(mTextTureId)
        // 当摄像头数据有更新回调 OnFrameAvailable
        mCameraTexture.setOnFrameAvailableListener(this)

        // 清理画布和缓存
        GLES20.glClearColor(0f, 0f, 0f, 0f)
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        mCameraFilter = CameraFilter(mCameraView.context)
    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {
        // opengl es
        GLES20.glViewport(0, 0, width, height)
    }

    override fun onDrawFrame(gl: GL10) {
        // 更新纹理
        mCameraTexture.updateTexImage()

        mCameraTexture.getTransformMatrix(mtx)

        mCameraFilter.onDraw(mtx, mTextTureId)
    }

    fun onSurfaceDestroyed() {
        mCameraFilter.release()
    }

    override fun onFrameAvailable(surfaceTexture: SurfaceTexture) {
        // 请求执行一次onDrawFrame
        mCameraView.requestRender()
    }

    /**
     * 更新
     * @param output 预览输出
     */
    override fun onUpdated(output: Preview.PreviewOutput) {
        // 摄像头图像纹理
        mCameraTexture = output.surfaceTexture
    }
}